home *** CD-ROM | disk | FTP | other *** search
- #import "ToyWin.h"
- #import <appkit/Application.h>
- #import <appkit/publicWraps.h>
- #import <appkit/SavePanel.h>
- #import <appkit/NXImage.h>
- #import <appkit/NXBitmapImageRep.h>
- #import <appkit/NXEPSImageRep.h>
- #import <appkit/Control.h>
- #import <objc/NXBundle.h> /* LocalizedString */
- #import <appkit/Panel.h>
- #import <appkit/tiff.h>
- #import <streams/streams.h> // NXStream
- #import <stdio.h>
- #import <stdlib.h>
- #import <string.h>
- #import <libc.h>
- #import "ToyView.h"
- #import "TVController.h"
- #import "TiffSavePanel.h"
- #import "common.h"
- #import "save.h"
-
- @implementation ToyWin (ImageSave)
-
- static char *mk_tmpname(const char *s, const char *ex, BOOL nopath)
- {
- static char srcfn[MAXFILENAMELEN];
- int i, j;
-
- if (nopath) {
- for (i = j = 0; s[i]; i++)
- if (s[i] == '/') j = i + 1;
- }else
- j = 0;
- strcpy(srcfn, s + j);
- for (i = j = 0; srcfn[i]; i++)
- if (srcfn[i] == '.') j = i + 1;
- if (j == 0)
- srcfn[i] = '.', j = i + 1;
- while (*ex)
- srcfn[j++] = *ex++;
- srcfn[j] = 0;
- return srcfn;
- }
-
-
- static char saveDir[MAXFILENAMELEN];
-
- - (char *)getSavename: (const char *)path with:(int)itype
- {
- SavePanel *savePanel;
- char *stmp, *sav = NULL;
- const char *ex = NULL;
-
- switch (itype) {
- case Type_eps: ex = "eps"; break;
- case Type_bmp: ex = "bmp"; break;
- case Type_gif: ex = "gif"; break;
- case Type_ppm: ex = "pnm"; break;
- }
- stmp = mk_tmpname(path, ex, YES);
- if (!saveDir[0])
- strcpy(saveDir, getenv("HOME"));
- savePanel = [SavePanel new];
- if ([savePanel runModalForDirectory: saveDir file: stmp]) {
- sav = mk_tmpname([savePanel filename], ex, NO);
- if (sav == NULL || *sav == 0)
- return NULL;
- strcpy(saveDir, [savePanel directory]);
- }
- return sav;
- }
-
- - (char *)getSaveTiffname: (const char *)path jpeg: (BOOL)flag
- compress: (int *)type by: (float *)factor
- {
- TiffSavePanel *savePanel;
- char *stmp, *sav = NULL;
- static float jpegFactor = 10.0; /* Default */
-
- stmp = mk_tmpname(path, "tiff", YES);
- if (!saveDir[0])
- strcpy(saveDir, getenv("HOME"));
- savePanel = [[TiffSavePanel new] init: jpegFactor jpeg: flag];
- if ([savePanel runModalForDirectory: saveDir file: stmp]) {
- sav = mk_tmpname([savePanel filename], "tiff", NO);
- if (sav == NULL || *sav == 0)
- return NULL;
- strcpy(saveDir, [savePanel directory]);
- [savePanel compressType: type with: factor];
- if (*type == NX_TIFF_COMPRESSION_JPEG)
- jpegFactor = *factor;
- }
- return sav;
- }
-
- - saveAsTiff: sender
- {
- NXStream *stream;
- int fd = -1;
- char *sav;
- commonInfo *cinf;
- NXBitmapImageRep *rep;
- BOOL jflag;
- int type;
- float factor;
-
- cinf = [[self toyView] commonInfo];
- rep = (NXBitmapImageRep *)[[[self toyView] image] bestRepresentation];
- jflag = (cinf->bits > 2 /* && cinf->type != Type_eps */
- && [rep canBeCompressedUsing: NX_TIFF_COMPRESSION_JPEG]);
- sav = [self getSaveTiffname: imageFilename jpeg: jflag
- compress: &type by: &factor];
- if (sav == NULL) /* canceled */
- return self;
- if ((fd = open(sav, O_WRONLY|O_CREAT|O_TRUNC, 0644)) < 0
- || (stream = NXOpenFile(fd, NX_WRITEONLY)) == NULL) {
- if (fd >= 0) (void) close(fd);
- errAlert(sav, Err_SAVE);
- return self;
- }
- if (factor < 1.0) factor = 1.0;
- else if (factor > 255.0) factor = 255.0;
- [rep writeTIFF:stream usingCompression:type andFactor:factor];
- NXClose(stream);
- (void)close(fd);
- return self;
- }
-
- - saveAsEPS: sender
- {
- NXStream *stream;
- char *sav;
- id tv;
- NXRect rect;
-
- sav = [self getSavename: imageFilename with:Type_eps];
- if (sav == NULL) /* canceled */
- return self;
- stream = NXOpenMemory(NULL, 0, NX_WRITEONLY);
- if (stream == NULL) {
- errAlert(sav, Err_MEMORY);
- return self;
- }
- tv = [self toyView];
- [tv getFrame:&rect];
- [tv copyPSCodeInside:&rect to:stream];
- NXFlush(stream);
- if (NXSaveToFile(stream, sav))
- errAlert(sav, Err_SAVE);
- NXCloseMemory(stream, NX_FREEBUFFER);
- return self;
- }
-
-
- /* Local Method */
- - saveFullColor:(FILE *)fp info:(commonInfo *)cinf
- colors:(int)cnum type:(int)itype map:(unsigned char **)map
- {
- const char *ask, *full, *reduce;
- paltype *pal = NULL;
- char msg[64];
- float bright;
-
- if (itype == Type_bmp) {
- ask = NXLocalizedString("Reduce Color?", NULL, BMP_Reduction);
- full = NXLocalizedString("Leave", NULL, BMP_Leave);
- reduce = NXLocalizedString("Reduce", NULL, BMP_Reduce);
- if (NXRunAlertPanel("", ask, full, reduce, NULL)) {
- saveBmpbmap(fp, cinf, cnum, NULL, map);
- return self;
- }
- }else /* gif */ {
- ask = NXLocalizedString("Reduction Start",
- NULL, GIF_Reduction);
- (void) NXRunAlertPanel("", ask, NULL, NULL, NULL);
- }
-
- [messagePanel makeKeyAndOrderFront: self];
- [messageText setStringValue:"Trying Reduction..."];
- [messagePanel setFloatingPanel: YES];
- NXPing();
- for ( bright = 0.0; ; ) {
- if (reduce_bright(&cnum, &bright, map)) break;
- sprintf(msg, "Trying Reduction: Brightness %d%%",
- (int)(bright * 100.0));
- [messageText setStringValue: msg];
- NXPing();
- }
- [messageText setStringValue: "Making Palette..."];
- NXPing();
- pal = get256map(&cnum);
- [messageText setStringValue: "Writing Image..."];
- NXPing();
- if (itype == Type_bmp)
- saveBmpbmap(fp, cinf, cnum, pal, map);
- else {
- resetPixel(map, 0);
- GIFEncode(fp, cinf, cnum, pal);
- }
- [messagePanel setFloatingPanel: NO];
- [messagePanel close];
-
- return self;
- }
-
-
- - (int)getBitmap:(unsigned char **)map info:(commonInfo **)infp
- {
- NXImageRep *rep;
- rep = [[[self toyView] image] bestRepresentation];
- [(NXBitmapImageRep *)rep getDataPlanes: map];
- return 0;
- }
-
- - freeTempBitmap
- {
- return self;
- }
-
- - saveAs: (int)itype
- {
- FILE *fp;
- char *sav;
- commonInfo *cinf;
- unsigned char *map[5];
- int cnum, err;
-
- cinf = [[self toyView] commonInfo];
- if (cinf->cspace == NX_CMYKColorSpace) {
- errAlert(imageFilename, Err_SAV_IMPL);
- return self;
- }
-
- sav = [self getSavename: imageFilename with: itype];
- if (sav == NULL) /* canceled */
- return self;
- if ((fp = fopen(sav, "w")) == NULL) {
- errAlert(sav, Err_SAVE);
- return self;
- }
-
- err = [self getBitmap:map info: &cinf];
-
- if (err == 0 && (err = initGetPixel(cinf)) == 0) {
- if (itype == Type_ppm) {
- resetPixel(map, 0);
- if ((err = ppmwrite(fp, cinf, map)) == 0)
- goto EXIT;
- }else {
- if (cinf->palette) {
- err = getAllPalColor();
- cnum = cinf->palsteps;
- }else
- err = getAllColor(&cnum, map);
- }
- }
- if (err) {
- errAlert(sav, err);
- (void)fclose(fp);
- (void)unlink(sav);
- return self;
- }
-
- if (cnum > FIXcount) /* bmp / gif */
- [self saveFullColor: fp
- info: cinf colors: cnum type: itype map: map];
- else {
- paltype *pal = cinf->palette;
- if (pal == NULL)
- pal = getNormalmap(&cnum);
- if (itype == Type_bmp)
- saveBmpbmap(fp, cinf, cnum, pal, map);
- else {
- resetPixel(map, 0);
- GIFEncode(fp, cinf, cnum, pal);
- }
- }
- EXIT:
- free256map();
- (void)fclose(fp);
- [self freeTempBitmap];
- return self;
- }
-
- - print: sender
- {
- [[self toyView] printPSCode:sender];
- return self;
- }
-
- @end
-